/*
 * Copyright (c) 2021 Talkweb Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <hi_early_debug.h>
#include <hi_i2c.h>
#include "JYRTC_rtc.h"
#include <hi_task.h>
#include <hi_time.h>
#include <hi_stdlib.h>
#include <hi_errno.h>
#include "ssd1306_oled.h"
#include "iot_gpio.h"
#define have_oled 1


hi_u32 g_rtc_demo_task_id =0;
ds1307_rtc_type rct_time_set ={0};
/*写寄存器*/
hi_u32 ds1307_i2c_write( hi_u8 reg_addr, hi_u8 high_8, hi_u8 low_8, hi_u8 reg_len)
{
    hi_u32 status =0;
    hi_i2c_idx id = HI_I2C_IDX_0;
    hi_i2c_data ds1307_i2c_write_cmd_addr ={0};
    hi_u8 temp1 =0; 
    hi_u8 temp2 =0;
    temp1 = (high_8/10*16)+(high_8%10); //16进制转BCD  
    temp2 = (low_8/10*16)+(low_8%10); //16进制转BCD  
    // printf("temp1= %x, temp2 = %x \r\n", temp1, temp2);
    hi_u8 _send_user_cmd[SEND_BUF_LEN] = {reg_addr, temp1, temp2};

    ds1307_i2c_write_cmd_addr.send_buf = _send_user_cmd;
    ds1307_i2c_write_cmd_addr.send_len = reg_len;
    
    status = hi_i2c_write(id, (DS1307_ADDRESS<<1)|DS1307_WRITE_ADDRESS, &ds1307_i2c_write_cmd_addr);
    if (status != HI_ERR_SUCCESS) {
        printf("===== Error: ds1307 sensor I2C write cmd address status = 0x%x! =====\r\n", status);
        return status;
    }
    return HI_ERR_SUCCESS;
}
hi_u8 *ds1307_read(hi_u8 rtc_reg, hi_u32 recv_len, hi_u8 *rct_buf)
{
    // ds1307_rtc_type read_rtc;
    hi_u32 status = 0;
    hi_i2c_idx id =HI_I2C_IDX_0;
    hi_u8 recv_data[DS1307_REG_ARRAY_LEN] = { 0 };
    hi_i2c_data ds1307_i2c_data = { 0 };

    /* Request memory space */
    memset(rct_buf, 0x00, sizeof(rct_buf));
    memset(recv_data, 0x0, sizeof(recv_data));
    memset(&ds1307_i2c_data, 0x0, sizeof(hi_i2c_data));
    ds1307_i2c_data.receive_buf = recv_data;
    ds1307_i2c_data.receive_len = recv_len;
    
    status = hi_i2c_read(id, (DS1307_ADDRESS<<1)|DS1307_READ_ADDRESS, &ds1307_i2c_data);
    if (status != HI_ERR_SUCCESS) {
        printf("===== Error: ds1307 sencor I2C read status = 0x%x! =====\r\n", status);
        return status;
    }
    switch (rtc_reg) {
    case RCT_SECOND:
         rct_buf[0] = recv_data[0];
        break;
    case RCT_MINUTE:
         rct_buf[0] = recv_data[0];
         break;
    case RCT_HOUR:
         rct_buf[0]  =  recv_data[0];
         break;
    case RCT_DAY :
         rct_buf[0] =  recv_data[0]; 
         break;
    case RCT_DATE:
         rct_buf[0]  =  recv_data[0];
         break; 
    case RCT_MONTH:
         rct_buf[0]  =  recv_data[0]; 
         break; 
    case RCT_YEAR:
         rct_buf[0]  =  recv_data[0]; 
         break;          
    default:
        break;
    }
    return rct_buf;
}
/*rtc timer setting*/

hi_void DS1307_SetInit(const struct tm* time_value)
{
    if (time_value == NULL) {
        printf("time value is null\n");
		return;
	}

    //ds1307_rtc_type rct_time_set ={0};
   printf("DS1307_SetInit:%04d/%02d/%02d %02d:%02d:%02d",time_value->tm_year+1900, time_value->tm_mon+1,time_value->tm_mday, 
			 	                                                         time_value->tm_hour,time_value->tm_min,time_value->tm_sec);
    rct_time_set.rtc_second[0] = (hi_u8)time_value->tm_sec;
    rct_time_set.rtc_minue[0] = (hi_u8)time_value->tm_min;
    rct_time_set.rtc_hour[0] = (hi_u8)time_value->tm_hour;
    rct_time_set.rtc_day[0] = (hi_u8)time_value->tm_wday;
    rct_time_set.rtc_date[0] = (hi_u8)time_value->tm_mday;
    rct_time_set.rtc_month[0] = (hi_u8)(time_value->tm_mon + 1);
    rct_time_set.rtc_year[0] = (hi_u8)((time_value->tm_year + 1900)-2000);
	return;
}

hi_void rct_set_init(hi_void)
{
    hi_u32 ret;
    //ds1307_rtc_type rct_time_set ={0};
    //rct_time_set.rtc_second[0] = 30;
    //rct_time_set.rtc_minue[0] =59;
    //rct_time_set.rtc_hour[0] = 23;
    //rct_time_set.rtc_day[0] = 5;
    //rct_time_set.rtc_date[0] = 31;
    //rct_time_set.rtc_month[0] = 12;
    //rct_time_set.rtc_year[0] = 21;
    //set second
    ret = ds1307_i2c_write(RCT_SECOND, rct_time_set.rtc_second[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to second cmd\r\n");
    }
    hi_udelay(DELAY_TIME); 
    //set minute
    ret = ds1307_i2c_write(RCT_MINUTE, rct_time_set.rtc_minue[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to minute cmd\r\n");
    }
    hi_udelay(DELAY_TIME); 
    //set hour
    ret = ds1307_i2c_write(RCT_HOUR, rct_time_set.rtc_hour[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to hour cmd\r\n");
    }
    hi_udelay(DELAY_TIME);
    //set day
    ret = ds1307_i2c_write(RCT_DAY, rct_time_set.rtc_day[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to day cmd\r\n");
    }
    hi_udelay(DELAY_TIME);
    //set date
    ret = ds1307_i2c_write(RCT_DATE, rct_time_set.rtc_date[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to date cmd\r\n");
    }
    hi_udelay(DELAY_TIME);  
    //set month
    ret = ds1307_i2c_write(RCT_MONTH, rct_time_set.rtc_month[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to month cmd\r\n");
    }
    hi_udelay(DELAY_TIME);   
    //set year
    ret = ds1307_i2c_write(RCT_YEAR, rct_time_set.rtc_year[0], NULL, SEND_SET_REG_LEN);
    if (ret != HI_ERR_SUCCESS) 
    {
        printf("Failed to year cmd\r\n");
    }
    hi_udelay(DELAY_TIME); 
}

/*  change type*/
hi_u8 *int_to_char(hi_s32 dec, hi_u8 *str)
{
    hi_u8 str1[40] = {0};
	hi_s32 j = 0;
    hi_s32 k = 0;
    hi_s32 i = 0;

	if (i == dec) 
    {
        str[0] = '0';
		return str;
	}

	i = (hi_s32)dec;//浮点数的整数部分
	while (i > 0) 
    {
		str1[j++] = i % 10 + '0';
		i = i / 10;
	}

	for (k = 0;k < j;k++) 
    {
		str[k] = str1[j-1-k];//被提取的整数部分正序存放到另一个数组
	}

	
    return str;
}

/*read rtc time*/
hi_void *rtc_timer(hi_void *param)
{
    hi_u8 rct_read_data[2] ={0};
    ds1307_rtc_type rtc_data ={0};
    hi_s32 temp_second =0;
    hi_s32 temp_minute =0;
    hi_s32 temp_hour =0;
    hi_s32 temp_day =0;
    hi_s32 temp_date =0;
    hi_s32 temp_month =0;
    hi_s32 temp_year =0;
    hi_u8 ch_year[5] ={0};
    hi_u8 ch_month[3] ={0};
    hi_u8 ch_day[3] ={0};
    hi_u8 ch_date[3] ={0};
    hi_u8 ch_hour[3] ={0};
    hi_u8 ch_minute[3] ={0};
    hi_u8 ch_second[3] ={0};

    char yearmd[48]={0};
    char hourms[48]={0};

    hi_unref_param(param);
    /*初始化时屏幕 i2c baudrate setting*/
	hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);
    hi_i2c_init(HI_I2C_IDX_0, 400000); /* baudrate: 400kbps */
    hi_i2c_set_baudrate(HI_I2C_IDX_0, 400000);
    /*ssd1306 config init*/
    
    //OLED_ShowString(8,16,"hello world",16);

    //OLED_Refresh();
    //rct_set_init(); //设置RTC时间，已经设置好了，如有需要再打开
    //oled_fill_screen(OLED_CLEAN_SCREEN);//clean screen  
    if(have_oled){
        oled_init();
        OLED_ColorTurn(0);//0正常显示，1 反色显示
        OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
        OLED_Refresh();

        while (1) 
    {

        /*----------------------second--------------*/
        ds1307_i2c_write(0x00, NULL, NULL, SEND_READ_DATA_LEN);  
        ds1307_read(RCT_SECOND, SEND_READ_DATA_LEN, rct_read_data);

        if (rtc_data.rtc_second[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_second[0] = rct_read_data[0];
            //temp_second = rct_read_data[0]/16*10 + rct_read_data[0]%16;
            temp_second = ((rct_read_data[0]>>4)&0x0f)*10 + (rct_read_data[0]&0x0f);
		    memset(ch_second, 0, 3);
            int_to_char(temp_second, ch_second);
            if (temp_second>=10) 
            {               
                //OLED_ShowString(36, 20, ch_second, 12);//oled_show_str(48, 6, ch_second, 1);
                printf("have_oled rtc_timer ch_second=%s\n",ch_second);
            } 
            else 
            {
                //OLED_ShowString(36, 20, "0", 12);
                //OLED_ShowString(42, 20, ch_second, 12);
                printf("have_oled rtc_timer ch_second=%s\n",ch_second);
            }
			//OLED_ShowString(48, 20, ".", 12);
        } 
        /*----------------------minute--------------*/
        ds1307_i2c_write(0x01, NULL, NULL, SEND_READ_DATA_LEN);   
        ds1307_read(RCT_MINUTE, SEND_READ_DATA_LEN, rct_read_data);
        if (rtc_data.rtc_minue[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_minue[0] = rct_read_data[0];
            temp_minute = rct_read_data[0]/16*10 + rct_read_data[0]%16;
		    memset(ch_minute, 0, 3);
            int_to_char(temp_minute, ch_minute);
            if (temp_minute >= 10) 
            {
                //OLED_ShowString(18, 20, ch_minute, 12);
                printf("have_oled rtc_timer ch_minute=%s\n",ch_minute);
                //OLED_ShowString(30, 20, ":", 12);
            } 
            else 
            {
                //OLED_ShowString(18, 20, "0", 12); 
                //OLED_ShowString(24, 20, ch_minute, 12);
                printf("have_oled rtc_timer ch_minute=%s\n",ch_minute);
                //OLED_ShowString(30, 20, ":", 12);
            }
            //OLED_ShowString(56, 6, "0", 12);                    
        }

        /*----------------------hour--------------*/
        ds1307_i2c_write(0x02, NULL, NULL, SEND_READ_DATA_LEN);  
        ds1307_read(RCT_HOUR, SEND_READ_DATA_LEN, rct_read_data);
		
        if (rtc_data.rtc_hour[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_hour[0] = rct_read_data[0];
            temp_hour = rct_read_data[0]/16*10 + rct_read_data[0]%16;
		    memset(ch_hour, 0, 3);
            int_to_char(temp_hour, ch_hour);
            if (temp_hour >= 10) 
            {
                //OLED_ShowString(0, 20, ch_hour, 12);
                printf("have_oled rtc_timer ch_hour=%s\n",ch_hour);
                //OLED_ShowString(12, 20, ":", 12);
            }
            else
            {
                //OLED_ShowString(0, 20, "0", 12);
                //OLED_ShowString(6, 20, ch_hour, 12);
                printf("have_oled rtc_timer ch_hour=%s\n",ch_hour);
                //OLED_ShowString(12, 20, ":", 12);
            }
            //OLED_ShowString(64, 6, " ", 12);
        }

        /*----------------------day-------------*/
        ds1307_i2c_write(0x03, NULL, NULL, SEND_READ_DATA_LEN);            
        ds1307_read(RCT_DAY, SEND_READ_DATA_LEN, rct_read_data);
		
        if (rtc_data.rtc_day[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_day[0] = rct_read_data[0];
            temp_day = rct_read_data[0]/16*10 + rct_read_data[0]%16;
            if(temp_day>7)
            {
                temp_day = temp_day-5;
            }
            else if(temp_day<=0)
            {
                temp_day = 1;
            }
		    memset(ch_day, 0, 3);
            int_to_char(temp_day, ch_day);
            //OLED_ShowString(0, 34, "week:", 12);
            //OLED_ShowString(36, 34, ch_day, 12);
            printf("have_oled rtc_timer ch_day=%s\n", ch_day);
        }
        /*----------------------date--------------*/
        ds1307_i2c_write(0x04, NULL, NULL, SEND_READ_DATA_LEN);      
        ds1307_read(RCT_DATE, SEND_READ_DATA_LEN, rct_read_data);
		
        if (rtc_data.rtc_date[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_date[0] = rct_read_data[0];
            temp_date = rct_read_data[0]/16*10 + rct_read_data[0]%16;
		    memset(ch_date, 0, 3);
            int_to_char(temp_date, ch_date);
            if (temp_date >= 10) 
            {               
                //OLED_ShowString(48, 6, ch_date, 12);
                printf("have_oled rtc_timer ch_date=%s\n",ch_date);
            } 
            else 
            {
                //OLED_ShowString(48, 6, "0", 12);
                //OLED_ShowString(54, 6, ch_date, 12);
                printf("have_oled rtc_timer ch_date=%s\n",ch_date);
            }
			//OLED_ShowString(60, 20, ".", 12);
        }

        /*----------------------month--------------*/
        ds1307_i2c_write(0x05, NULL, NULL, SEND_READ_DATA_LEN); 
        ds1307_read(RCT_MONTH, SEND_READ_DATA_LEN, rct_read_data);
		
        if (rtc_data.rtc_month[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_month[0] = rct_read_data[0];
            temp_month = rct_read_data[0]/16*10 + rct_read_data[0]%16;
		    memset(ch_month, 0, 3);
            int_to_char(temp_month, ch_month);
            if (temp_month >= 10) 
            {
                //OLED_ShowString(30, 6, ch_month, 12);
                printf("have_oled rtc_timer ch_month=%s\n",ch_month);
                //OLED_ShowString(30, 6, "-", 12); 
            } 
            else 
            {
                //OLED_ShowString(30, 6, "0", 12);
                //OLED_ShowString(36, 6, ch_month, 12);
                printf("have_oled rtc_timer ch_month=%s\n",ch_month);
               // OLED_ShowString(30, 5, "-", 12);
            }
        }

        /*----------------------year--------------*/
        ds1307_i2c_write(0x06, NULL, NULL, SEND_READ_DATA_LEN);            
        ds1307_read(RCT_YEAR, SEND_READ_DATA_LEN, rct_read_data);
		
        if (rtc_data.rtc_year[0] != rct_read_data[0]) 
        {
            rtc_data.rtc_year[0] = rct_read_data[0];
            temp_year = rct_read_data[0]/16*10 + rct_read_data[0]%16;
            temp_year=temp_year+2000;
		    memset(ch_year, 0, 5);
            int_to_char(temp_year, ch_year);
            //OLED_ShowString(0, 6, "20", 12);
            //OLED_ShowString(12, 6, ch_year, 12);
            printf("have_oled rtc_timer ch_year=%s\n",ch_year);
            //OLED_ShowString(32, 6, "-", 12);
        }
        
    if (sprintf_s(yearmd,48,"%04d:%02d:%02d",temp_year, temp_month, temp_date) == -1) 
    {
        printf("sprintf time error\n");
    }

    if (sprintf_s(hourms,48,"%02d:%02d:%02d",temp_hour, temp_minute, temp_second) == -1) 
    {
        printf("sprintf time error\n");
    }
    printf("have_oled rtc_timer yearmd=%s\n",yearmd);
    printf("have_oled rtc_timer hourms=%s\n",hourms);
    OLED_ShowString(0, 6, yearmd, 12);
    OLED_ShowString(0, 20, hourms, 12);    
	OLED_Refresh();
    hi_sleep(1);
    }
    }
    else
    {
        while (1) 
        {

            /*----------------------second--------------*/
            ds1307_i2c_write(0x00, NULL, NULL, SEND_READ_DATA_LEN);  
            ds1307_read(RCT_SECOND, SEND_READ_DATA_LEN, rct_read_data);

            if (rtc_data.rtc_second[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_second[0] = rct_read_data[0];
                //temp_second = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                temp_second = ((rct_read_data[0]>>4)&0x0f)*10 + (rct_read_data[0]&0x0f);
                memset(ch_second, 0, 3);
                int_to_char(temp_second, ch_second);
                if (temp_second>=10) 
                {               
                    printf("have_oled rtc_timer ch_second=%s\n", ch_second);
                } 
                else 
                {
                    printf("have_oled rtc_timer ch_second=%s\n", ch_second);
                }
            } 
            /*----------------------minute--------------*/
            ds1307_i2c_write(0x01, NULL, NULL, SEND_READ_DATA_LEN);   
            ds1307_read(RCT_MINUTE, SEND_READ_DATA_LEN, rct_read_data);
            if (rtc_data.rtc_minue[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_minue[0] = rct_read_data[0];
                temp_minute = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                memset(ch_minute, 0, 3);
                int_to_char(temp_minute, ch_minute);
                if (temp_minute >= 10) 
                {
                    printf("have_oled rtc_timer ch_minute=%s\n",ch_minute);
                } 
                else 
                {
                    printf("have_oled rtc_timer ch_minute=%s\n",ch_minute);
                }              
            }

            /*----------------------hour--------------*/
            ds1307_i2c_write(0x02, NULL, NULL, SEND_READ_DATA_LEN);  
            ds1307_read(RCT_HOUR, SEND_READ_DATA_LEN, rct_read_data);
            
            if (rtc_data.rtc_hour[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_hour[0] = rct_read_data[0];
                temp_hour = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                memset(ch_hour, 0, 3);
                int_to_char(temp_hour, ch_hour);
                if (temp_hour >= 10) 
                {
                    printf("have_oled rtc_timer ch_hour=%s\n",ch_hour);
                } 
                else
                {
                    printf("have_oled rtc_timer ch_hour=%s\n",ch_hour);
                }
            }

            /*----------------------day-------------*/
            ds1307_i2c_write(0x03, NULL, NULL, SEND_READ_DATA_LEN);            
            ds1307_read(RCT_DAY, SEND_READ_DATA_LEN, rct_read_data);
            
            if (rtc_data.rtc_day[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_day[0] = rct_read_data[0];
                temp_day = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                if(temp_day > 7)
                {
                    temp_day=temp_day-5;
                }
                else if
                (temp_day <= 0)
                {
                    temp_day=1;
                }
                memset(ch_day, 0, 3);
                int_to_char(temp_day, ch_day);
                printf("have_oled rtc_timer ch_day=%s\n", ch_day);
            }
            /*----------------------date--------------*/
            ds1307_i2c_write(0x04, NULL, NULL, SEND_READ_DATA_LEN);      
            ds1307_read(RCT_DATE, SEND_READ_DATA_LEN, rct_read_data);
            
            if (rtc_data.rtc_date[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_date[0] = rct_read_data[0];
                temp_date = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                memset(ch_date, 0, 3);
                int_to_char(temp_date, ch_date);
                if (temp_date >= 10) 
                {               
                    printf("have_oled rtc_timer ch_date=%s\n",ch_date);
                } 
                else 
                {
                    printf("have_oled rtc_timer ch_date=%s\n",ch_date);
                }
            }

            /*----------------------month--------------*/
            ds1307_i2c_write(0x05, NULL, NULL, SEND_READ_DATA_LEN); 
            ds1307_read(RCT_MONTH, SEND_READ_DATA_LEN, rct_read_data);
            
            if (rtc_data.rtc_month[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_month[0] = rct_read_data[0];
                temp_month = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                memset(ch_month, 0, 3);
                int_to_char(temp_month, ch_month);
                if (temp_month >= 10) 
                {
                    printf("have_oled rtc_timer ch_month=%s\n", ch_month);
                } 
                else 
                {
                    printf("have_oled rtc_timer ch_month=%s\n", ch_month);
                }
            }

            /*----------------------year--------------*/
            ds1307_i2c_write(0x06, NULL, NULL, SEND_READ_DATA_LEN);            
            ds1307_read(RCT_YEAR, SEND_READ_DATA_LEN, rct_read_data);
            
            if (rtc_data.rtc_year[0] != rct_read_data[0]) 
            {
                rtc_data.rtc_year[0] = rct_read_data[0];
                temp_year = rct_read_data[0]/16*10 + rct_read_data[0]%16;
                temp_year = temp_year+2000;
                memset(ch_year, 0, 5);
                int_to_char(temp_year, ch_year);
                printf("have_oled rtc_timer ch_year=%s\n", ch_year);
            }        
            hi_sleep(1);
        }
    }
}

